//
// Copyright (c) 2009 All Right Reserved
//
// vl
//
// 2009-01-01
// Contains ...
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
namespace LargoCommon.Music
{
///
/// TODO: Update summary.
///
public class MelodicStreamAnalyzer {
#region Constructors
///
/// Initializes a new instance of the class.
///
/// The given melodic items.
public MelodicStreamAnalyzer(IList givenMelodicItems) {
Contract.Requires(givenMelodicItems != null);
this.MelodicItems = givenMelodicItems;
this.EstimateMotiveMarkers();
}
#endregion
#region Properties
///
/// Gets the melodic items.
///
///
/// The melodic items.
///
private IList MelodicItems { get; }
#endregion
#region String representation
/// String representation of the object.
/// Returns value.
public override string ToString() {
return $"MelodicStreamAnalyzer (Number of items {this.MelodicItems.Count})";
}
#endregion
#region Public methods
///
/// Gets the next motive items.
///
/// The line number.
/// Returns value.
public IList GetNextMotiveItems(int lineIndex) {
if (this.MelodicItems == null) {
return null;
}
var motiveItems = new List();
var motiveStarted = false;
var trackItems = this.MelodicItems.Where(it => it.LineIndex == lineIndex && !it.IsCovered).ToList();
foreach (var item in trackItems) {
if (item.RhythmicStructure == null || item.RhythmicStructure.ToneLevel == 0) { //// 2018/12 above: || item.IsCovered
continue;
}
if (item.IsLikeMotiveStart) {
motiveStarted = true;
}
if (motiveStarted) {
item.IsCovered = true;
motiveItems.Add(item);
if (item.IsLikeMotiveEnd) {
break;
}
}
}
return motiveItems;
}
#endregion
#region Private methods
///
/// Prepares the line breaks.
///
private void EstimateMotiveMarkers() { //// Start and ends
MelodicItem previousItem = null;
if (this.MelodicItems == null) {
return;
}
foreach (var melodicItem in this.MelodicItems) {
if (previousItem != null && melodicItem.LineIndex != previousItem.LineIndex) {
previousItem = null; //// Next Line ...
}
if (melodicItem.RhythmicStructure == null) {
continue;
}
if (previousItem != null && melodicItem.MusicalBar.BarNumber - previousItem.MusicalBar.BarNumber > 1)
{
previousItem.IsLikeMotiveEnd = true;
melodicItem.IsLikeMotiveStart = true;
previousItem = melodicItem;
continue;
}
//// var nextBar = melodicItem.MusicalBar.NextBar; var motiveEnd = musicalBar.IsLastInHarmonicMotive;
//// var motiveStart = melodicItem.MusicalBar.IsFirstInHarmonicMotive && melodicItem.MusicalTones.HasAnySoundingTone;
//// if (!motiveStart) {
if (melodicItem.MelodicTones == null || !melodicItem.MelodicTones.Any()) { //// 201509
//// 2016/04 Rhythmic tracks!?
melodicItem.IsLikeMotiveStart = melodicItem.MusicalTones != null && melodicItem.MusicalTones.Any();
previousItem = melodicItem;
continue;
}
if (previousItem != null) {
if (previousItem.MelodicTones == null || !previousItem.MelodicTones.Any()) { //// 201509
previousItem = melodicItem;
continue;
}
if (!previousItem.IsLikeMotiveEnd) {
previousItem.IsLikeMotiveEnd = previousItem.MelodicTones.Any() && !melodicItem.MelodicTones.Any();
}
if (!melodicItem.IsLikeMotiveEnd && melodicItem.MelodicTones.Any()) {
melodicItem.IsLikeMotiveEnd = ((melodicItem.RhythmicStructure.ToneLevel < previousItem.RhythmicStructure.ToneLevel)
&& !melodicItem.RhythmicStructure.StartsWithFormalRest)
|| melodicItem.RhythmicStructure.EndsWithFormalRest;
}
melodicItem.IsLikeMotiveStart = (previousItem.IsLikeMotiveEnd || !previousItem.MelodicTones.Any())
&& melodicItem.MelodicTones.Any();
if (!melodicItem.IsLikeMotiveStart && melodicItem.RhythmicStructure != null) {
melodicItem.IsLikeMotiveStart = melodicItem.RhythmicStructure.StartsWithFormalRest;
}
}
else {
melodicItem.IsLikeMotiveStart = true;
}
//// The assumed motive continues.
if (previousItem != null && previousItem.IsLikeMotiveEnd && melodicItem.IsLikeMotiveStart && melodicItem.IsLikeMotiveEnd) {
previousItem.IsLikeMotiveEnd = false;
melodicItem.IsLikeMotiveStart = false;
}
previousItem = melodicItem;
}
}
#endregion
}
}